#include <qlabel.h>
#include <qlineedit.h>
#include <qtableview.h>
#include <qstring.h>
#include <qtextedit.h>
#include <qpushbutton.h>
#include <iostream>
#include "BrainGUI.h"
#include <stdio.h>
#include <fcntl.h>
#include <qfiledialog.h>
#include <qerrormessage.h>
#include <pthread.h>

/* Global array holding all the process colors */
QColor procColors[MAXPROCS] = {Qt::black, Qt::red, Qt::green, Qt::blue, Qt::cyan, Qt::magenta, Qt::yellow, Qt::gray, Qt::darkRed, Qt::darkBlue, Qt::darkCyan, Qt::darkGreen};

BrainGUI::BrainGUI(QWidget* parent) : QWidget(parent)
{
	m_bRunning = false;
	m_nCanContinue = 0;

	setWindowTitle("BRAIN '09");

	/* Initialize Widgets */
	m_brainFileView = new QTextEdit("Line1\n");
	m_brainFileView->setReadOnly(true);
	m_pathLabel = new QLabel("Brain file path:");
	m_brainpathEdit = new QLineEdit();
	m_browseBtn = new QPushButton("Browse");
	m_startcontBtn = new QPushButton("Start");

	/* Init the tab widget to hold the programs running */
	m_processTabs = new QTabWidget();	
	m_processTabs->insertTab(0, m_brainFileView, "Process 1");

	/* Create the memory view with one for main memory and one for shared memory */
	QVBoxLayout* memLayout = new QVBoxLayout();
	
	m_memFrame = new QFrame();
	m_memFrame->setFrameStyle(QFrame::WinPanel);
	
	m_mainMemBlock = new MemBlock();
	m_sharedMemBlock = new MemBlock();
	
	QLabel* mainLbl = new QLabel("Main Memory");
	mainLbl->setAlignment(Qt::AlignHCenter);
	
	memLayout->addWidget(mainLbl);
	memLayout->addWidget(m_mainMemBlock);
	
	QLabel* sharedLbl = new QLabel("Shared Memory");
	sharedLbl->setAlignment(Qt::AlignHCenter);
	
	memLayout->addWidget(sharedLbl);
	memLayout->addWidget(m_sharedMemBlock);
	m_memFrame->setLayout(memLayout);

	/* Store a label, path line edit, and load button in a horizontal layout */
	QHBoxLayout* fileLayout = new QHBoxLayout();
	fileLayout->addWidget(m_pathLabel);
	fileLayout->addWidget(m_brainpathEdit);
	fileLayout->addWidget(m_browseBtn);
	fileLayout->addWidget(m_startcontBtn);

	/* Overall layout is a vertical box */
	m_mainLayout = new QGridLayout();
	m_mainLayout->addWidget(m_memFrame, 0, 0, 1, 6);
	m_mainLayout->addWidget(m_processTabs, 1, 0, 5, 1);
	m_mainLayout->addLayout(fileLayout, 6, 0, 1, 1);
	m_mainLayout->setColumnMinimumWidth(0, 500);
	m_mainLayout->setColumnMinimumWidth(1, 20);
	m_mainLayout->setColumnMinimumWidth(2, 50);
	m_mainLayout->setColumnMinimumWidth(3, 50);
	m_mainLayout->setColumnMinimumWidth(4, 50);
	m_mainLayout->setColumnMinimumWidth(5, 50);
	setLayout(m_mainLayout);
	
	/* Connect the require signals */
	QObject::connect(m_browseBtn, SIGNAL(clicked(bool)), this, SLOT(GetBrainFilePath(void)));
	QObject::connect(m_startcontBtn, SIGNAL(clicked(bool)), this, SLOT(StartContinue(void)));

	/* Create the legend */
	SetupLegend();
}

void BrainGUI::AddLine(char* string)
{
	m_brainFileView->append(QString(string));
	std::cout << "inside AddText" << std::endl;
}

void BrainGUI::GetBrainFilePath(void)
{
	m_brainPath = QFileDialog::getOpenFileName(this, QString("Select Brain File"), QString("./"));
	if(!(m_brainPath.isNull()))
		m_brainpathEdit->setText(m_brainPath);
}

int BrainGUI::CanContinue(void)
{
	return m_nCanContinue;
}

void BrainGUI::StartContinue(void)
{
	if(m_bRunning){
		/* Set a continuing flag */
		m_nCanContinue = 1;
	}
	else{
		pthread_t tid;
		/* Start the brain program with the specified path */
		pthread_create(&tid, NULL, &startbrain, (void*)(const char*)(m_brainPath.toAscii()));
		pthread_detach(tid);
		//startbrain((const char*)(m_brainPath.toAscii()));
		m_startcontBtn->setText("Continue");
		m_bRunning = true;
	}
}

void BrainGUI::SetupLegend(void)
{
	int i = 0;
	int nLegendCurrCol = 2, nLegendCurrRow = 1;
		

	for(i = 0; i < MAXPROCS; i++){
		m_legend[i].procLbl = new QLabel(QString("Process ") + QString::number(i+1, 10));
		m_legend[i].colorBlock = new QWidget();

		/* Add a label and color block for each entry */
		m_mainLayout->addWidget(m_legend[i].procLbl, nLegendCurrRow, nLegendCurrCol, 1, 1);
		m_mainLayout->addWidget(m_legend[i].colorBlock, nLegendCurrRow, nLegendCurrCol +1 , 1, 1);
		
		/* Move over to the second column of processes in the legend */
		if(nLegendCurrRow != 6)
			nLegendCurrRow++;
		else{
			nLegendCurrRow = 1;
			nLegendCurrCol = 4;
		}	
	}
	
	/* Update calls paintEvent to paint the color patches */
	update();
}

void BrainGUI::paintEvent(QPaintEvent* /*event*/)
{
	int i = 0;

	/* Paint a rectangle of each processes color, unfortunately these may need to be static */
	QPainter painter(this);

	for(i = 0; i < MAXPROCS; i++){
		painter.setPen(procColors[i]);
		painter.setBrush(procColors[i]);

		painter.save();
		painter.drawRect(QRect(((m_legend[i].colorBlock->pos()).x()) + 6, ((m_legend[i].colorBlock->pos()).y()) + 6, m_legend[i].colorBlock->width() - 5, 18));
		painter.restore();
	}
}

